package com.info33.platform.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.info33.platform.common.constant.TableConstant;
import com.info33.platform.common.mvc.vo.Result;
import com.info33.platform.system.dao.SysMenuUserDao;
import com.info33.platform.system.dto.SysAuthorityDetailDTO;
import com.info33.platform.system.dto.SysMenuUserDTO;
import com.info33.platform.system.entity.SysMenuUser;
import com.info33.platform.system.service.SysMenuUserService;
import com.info33.platform.system.vo.SysAuthorityDetailVO;
import com.info33.platform.system.vo.SysAuthorityVO;
import com.info33.platform.system.vo.SysMenuUserVO;
import com.info33.platform.system.vo.SysTenantMenuVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author admin
 */
@Service
@Transactional(rollbackFor = {Exception.class, Error.class})
public class SysMenuUserServiceImpl extends ServiceImpl<SysMenuUserDao, SysMenuUser> implements SysMenuUserService {

    @Autowired
    SysMenuUserDao sysMenuUserDao;

    @Override
    public IPage<SysAuthorityVO> pageMenuUserList(IPage<SysAuthorityVO> page, SysMenuUser sysMenuUser,
                                                  Long tenantId) {
        return sysMenuUserDao.pageMenuUserList(page, sysMenuUser, tenantId);
    }

    @Override
    public Result<?> saveMenuUser(SysMenuUserDTO sysMenuUserDTO, Long tenantId) {
        List<SysMenuUser> sysMenuUserList = new ArrayList<>();
        if (!StringUtils.isEmpty(sysMenuUserDTO.getType()) && 4 == sysMenuUserDTO.getType()) {
            for (Long userId : sysMenuUserDTO.getUserIdList()) {
                //过滤掉已有的权限
                sysMenuUserDTO.setUserId(userId);
                extracted(sysMenuUserDTO, tenantId, sysMenuUserList);
            }
            if (CollectionUtils.isEmpty(sysMenuUserList)) {
                return Result.ok();
            }
            return saveBatch(sysMenuUserList) ? Result.ok(sysMenuUserList) : Result.error();
        }
        extracted(sysMenuUserDTO, tenantId, sysMenuUserList);
        if (CollectionUtils.isEmpty(sysMenuUserList)) {
            return Result.ok();
        }
        return saveBatch(sysMenuUserList) ? Result.ok(sysMenuUserList) : Result.error();
    }

    private void extracted(SysMenuUserDTO sysMenuUserDTO, Long tenantId, List<SysMenuUser> sysMenuUserList) {
        SysMenuUser menuUser = new SysMenuUser();
        BeanUtils.copyProperties(sysMenuUserDTO, menuUser);
        List<SysMenuUser> menuUserList = sysMenuUserDao.getByType(menuUser, tenantId);
        List<Long> menuIds = menuUserList.stream().map(SysMenuUser::getMenuId).collect(Collectors.toList());
        List<Long> menuIdList = sysMenuUserDTO.getMenuIdList().stream().filter(item -> !menuIds.contains(item)).collect(Collectors.toList());
        for (Long menuId : menuIdList) {
            SysMenuUser sysMenuUser = new SysMenuUser();
            BeanUtils.copyProperties(sysMenuUserDTO, sysMenuUser);
            sysMenuUser.setMenuId(menuId);
            sysMenuUserList.add(sysMenuUser);
        }
    }

    @Override
    public Result<?> editMenuUser(SysMenuUserDTO sysMenuUserDTO, Long tenantId) {
        //1.获取类型
        Integer type = sysMenuUserDTO.getType();
        //2.根据 type 和 对应id 删除所有权限
        QueryWrapper<SysMenuUser> wrapper = new QueryWrapper<SysMenuUser>();
        wrapper.eq("type", type).eq(TableConstant.TENANT_ID, tenantId);
        switch (type) {
            case 1:
                wrapper.eq("dept_id", sysMenuUserDTO.getDeptId());
                break;
            case 2:
                wrapper.eq("post_id", sysMenuUserDTO.getPostId());
                break;
            case 3:
                wrapper.eq("dept_id", sysMenuUserDTO.getDeptId()).eq("post_id", sysMenuUserDTO.getPostId());
                break;
            case 4:
                wrapper.eq("user_id", sysMenuUserDTO.getUserId());
                break;
            default:
                break;
        }
        sysMenuUserDao.delete(wrapper);
        //3.再进行新增
        List<SysMenuUser> sysMenuUserList = new ArrayList<SysMenuUser>();
        extracted(sysMenuUserDTO, tenantId, sysMenuUserList);
        if (CollectionUtils.isEmpty(sysMenuUserList)) {
            return Result.ok();
        }
        return saveBatch(sysMenuUserList) ? Result.ok(sysMenuUserList) : Result.error();
    }

    @Override
    public Result<?> batchRemove(List<SysAuthorityDetailDTO> authorityDetailList, Long tenantId) {
        List<Long> idList = new ArrayList<Long>();
        for (SysAuthorityDetailDTO sysAuthorityDetailDTO : authorityDetailList) {
            SysMenuUser sysMenuUser = extractedSysMenuUser(sysAuthorityDetailDTO, tenantId);
            List<SysMenuUser> menuUserList = sysMenuUserDao.getByType(sysMenuUser, tenantId);
            List<Long> ids = menuUserList.stream().map(SysMenuUser::getId).collect(Collectors.toList());
            idList.addAll(ids);
        }

        return sysMenuUserDao.deleteBatchIds(idList) > 0 ? Result.ok() : Result.error();
    }

    @Override
    public SysAuthorityDetailVO getDetail(SysAuthorityDetailDTO sysAuthorityDetailDTO, Long tenantId) {
        SysMenuUser sysMenuUser = extractedSysMenuUser(sysAuthorityDetailDTO, tenantId);
        //根据type、id查询对应菜单
        List<SysTenantMenuVO> menuList = sysMenuUserDao.getMenuByType(sysMenuUser);
        SysAuthorityDetailVO sysAuthorityDetailVO = new SysAuthorityDetailVO();
        BeanUtils.copyProperties(sysAuthorityDetailDTO, sysAuthorityDetailVO);
        if (5 != sysMenuUser.getType()) {
            sysAuthorityDetailVO.setName(sysMenuUserDao.getNameByType(sysMenuUser));
        }
        sysAuthorityDetailVO.setMenuList(menuList);
        return sysAuthorityDetailVO;
    }

    private SysMenuUser extractedSysMenuUser(SysAuthorityDetailDTO sysAuthorityDetailDTO, Long tenantId) {
        Integer type = sysAuthorityDetailDTO.getType();
        String id = sysAuthorityDetailDTO.getId();
        //根据类型判断所属id
        SysMenuUser sysMenuUser = new SysMenuUser();
        sysMenuUser.setType(type);
        sysMenuUser.setTenantId(tenantId);
        switch (type) {
            case 1:
                sysMenuUser.setDeptId(Long.valueOf(id));
                break;
            case 2:
                sysMenuUser.setPostId(Long.valueOf(id));
                break;
            case 3:
                String[] idArray = id.split(",");
                sysMenuUser.setDeptId(Long.valueOf(idArray[0]));
                sysMenuUser.setPostId(Long.valueOf(idArray[1]));
                break;
            case 4:
                sysMenuUser.setUserId(Long.valueOf(id));
                break;
            default:
                break;
        }
        return sysMenuUser;
    }

    @Override
    public Map<Integer, List<SysMenuUserVO>> getAuthority(Long menuId) {
        List<SysMenuUserVO> sysMenuUserVOList = sysMenuUserDao.getAuthority(menuId);
        //根据type字段进行分组
        return sysMenuUserVOList.stream().collect(
                Collectors.groupingBy(
                        sysMenuUserVO -> sysMenuUserVO.getType()
                ));
    }

}